package rsvp;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;


public class AverageTextStatistics {
	
	final NumberFormat FLOAT_FORMAT = new DecimalFormat("0.0");
	final NumberFormat GROUPED_DECIMAL_FORMAT = new DecimalFormat("###,###");
	final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss");
	
	public int iNumberOfWords;
	public double lfAverage_IndividualWordLength;
	/**
	 * this is calculated based on the minimum number of characters to display and based on how the words fall on it
	 */
	public double lfAverage_WordDisplayLength;
	public int iRemainingWords;
	private String fileLocation;

	/*- 
	 * defines variables needed to determine what is the real reading speed
	 */
	/**
	 * after this period of time restart speed start reference 
	 */
	private static final long TIME_UNTIL_RESTART = 60*60*1000;
	
	/**
	 * When did the reading speed measurement start
	 */
	Date dtReadStart = null;

	/**
	 * When was the reading last updated.
	 * This option is useful when we want to reset automatically the reading speed measurement 
	 */
	Date dtReadLastUpdated = new Date();
	
	/**
	 * What was the position when the reading started.
	 */
	int iReadStartRemainingWords = 0;
	/**
	 * keeps a reference to the text from the main panel
	 */
	private String m_textReference;
		


	/**
	 * 
	 */
	public void printVerboseStatistics_onStart() {
		
		System.out.println(fileLocation);
		System.out.println("Average length: " + FLOAT_FORMAT.format(this.lfAverage_IndividualWordLength));
		System.out.println("Remaining percentage: " + FLOAT_FORMAT.format((((double)iRemainingWords / iNumberOfWords) * 100)) + "% ");
		System.out.println("Words Remaining : "
				+ FLOAT_FORMAT.format(iRemainingWords / (float) this.lfAverage_IndividualWordLength)
				+ " (estimated)");
		System.out.println("Number of Words : " + this.iNumberOfWords);
		System.out.println("Real WPM: " + (long)getAverageWPM() + " ");
		System.out.println("Estimated Duration: " + FLOAT_FORMAT.format(getRemainingDuration()) + " minutes");
		System.out.println(getETA());
		System.out.println("");
	}


	/**
	 * @return 
	 */
	public String getPrintableLabelStatistic() {
		
		String stat = "Remaining (words): " + FLOAT_FORMAT.format((((double)iRemainingWords / iNumberOfWords) * 100)) + "%;  "; 
		stat += GROUPED_DECIMAL_FORMAT.format(this.iReadStartRemainingWords - iRemainingWords) + 
			"+" + GROUPED_DECIMAL_FORMAT.format(iRemainingWords) + 
			"~" + GROUPED_DECIMAL_FORMAT.format(iNumberOfWords) + "; ";
		// Start
		stat += "   Started: " + DATE_FORMAT.format(dtReadStart) + " ";
		// duration			
		stat += "   Duration (minutes): " + FLOAT_FORMAT.format(getElapsedReadingTime())
				+ "+" + FLOAT_FORMAT.format(getRemainingDuration()) 
				+ "~" + FLOAT_FORMAT.format(getElapsedReadingTime() + getRemainingDuration());
		stat += "   Average WPM: " + (long)getAverageWPM() + " ";
		stat += getETA();
		
		
		
		return stat;
	}

	/**
	 * @return
	 */
	private double getElapsedReadingTime()
	{
		long ms = new Date().getTime() - dtReadStart.getTime();
		return (double)ms / (60*1000);
	}


	/**
	 * @return
	 */
	private double getAverageWPM()
	{
		// 1. initialize/update status object
		Date dtNow = new Date();
		if ((dtNow.getTime() - dtReadLastUpdated.getTime()) > TIME_UNTIL_RESTART ) {
			resetReadStatistics();
		}
					
		if (null == dtReadStart || (iReadStartRemainingWords < iRemainingWords)) {
			dtReadStart = new Date();
			iReadStartRemainingWords = iRemainingWords;
		}
		
		
		dtReadLastUpdated = dtNow;

		// 2. compute real WPM
		double lfElapsedMinutes = (double) (dtNow.getTime() - dtReadStart.getTime()) / (60 * 1000);
		if (lfElapsedMinutes < 0.1)
			lfElapsedMinutes = 0.1;
//		System.out.println("iReadStartRemainingWords = " + iReadStartRemainingWords);
//		System.out.println("iRemainingWords = " + iRemainingWords);
		double real = (double)(iReadStartRemainingWords - iRemainingWords) / lfElapsedMinutes; 
		
		return real;
	}


	/**
	 * @return
	 */
	private String getETA()
	{
		// ETA
		Date dETA = new Date();
		dETA.setTime((long) (dETA.getTime() + getRemainingDuration() * 60 * 1000));
		
		return "   ETA: " + DATE_FORMAT.format(dETA) + " ";
	}

	/**
	 * @return
	 */
	private double  getRemainingDuration()
	{
		return (double)iRemainingWords / getAverageWPM();
	}
	
	/**
	 * @param lTimeDelayedInTotal the lTimeDelayedInTotal to set
	 */
	public void setFileLocation(String location)
	{
		this.fileLocation = location;
	}

	/**
	 *	it makes sometimes to reset the read statistics 
	 */
	public void resetReadStatistics() {

		dtReadStart = null;
	}


	/**
	 * @param text
	 */
	public void checkIfReadStatisticResetIsRequired(String text)
	{
		if (!text.equals(m_textReference)) {
			m_textReference = text;
			resetReadStatistics();
		}
	}
}
